`include "defines.v"
module ex_mem(
	input wire clk,
	input wire rst,
	input wire[31:0] write_data_i,
	input wire write_ce_i,
	input wire[4:0] write_addr_i,
	output reg[31:0] write_data_o,
	output reg write_ce_o,
	output reg[4:0] write_addr_o,
	
	//与hilo寄存器相关的数据
	input wire[31:0] hi_i,
	input wire[31:0] lo_i,
	input wire hilo_write_ce_i,
	output reg[31:0] hi_o,
	output reg[31:0] lo_o,
	output reg hilo_write_ce_o,
	input wire[5:0] pause, //流水线暂停信号

	input wire[63:0] hilo_temp_i, //乘法结果
	input wire[1:0] count_i, //下一个时钟周期是第几个执行周期
	output reg[63:0] hilo_temp_o, //乘法结果
	output reg[1:0] count_o, //当前时钟周期处于执行阶段的第几个周期
	
	//访存指令信号
	input wire[31:0] mem_addr_i,
	input wire[31:0] mem_wdata_i,
	input wire[`AluOpWidth-1:0] alu_op_i,
	output reg[31:0] mem_addr_o,
	output reg[31:0] mem_wdata_o,
	output reg[`AluOpWidth-1:0] alu_op_o,
	//CP0相关信号
	input wire[31:0] ex_cp0_wData_i,
	input wire[4:0] ex_cp0_wAddr_i,
	input wire ex_cp0_wCe_i,
	output reg[31:0] mem_cp0_wData_o,
	output reg[4:0] mem_cp0_wAddr_o,
	output reg mem_cp0_wCe_o
);
	
	always@(posedge clk)
		if(rst == `RstEnable)
		begin
			hilo_temp_o <= {`ZeroWord, `ZeroWord};
			count_o <= 2'b00;
		end
		else if(pause[3] == `PAUSE && pause[4] == `NO_PAUSE) 
		begin
			hilo_temp_o <= hilo_temp_i;
			count_o <= count_i;
		end
		else 
		begin
			hilo_temp_o <= {`ZeroWord, `ZeroWord};
			count_o <= 2'b00;
		end
		
	always@(posedge clk) 
		if(rst == `RstEnable)
		begin
			write_data_o <= `ZeroWord;
			write_ce_o <= `WriteDisable;
 			write_addr_o <= 5'b00000;
			hi_o <= `ZeroWord;
			lo_o <= `ZeroWord;
			hilo_write_ce_o <= `WriteDisable;
			
			mem_addr_o <= `ZeroWord;
			mem_wdata_o <= `ZeroWord;
			alu_op_o <= `ALU_NOP_OP;
			
			mem_cp0_wData_o <= `ZeroWord;
			mem_cp0_wAddr_o <= 5'b00000;
			mem_cp0_wCe_o <= `WriteDisable;
		end
		else if(pause[3] == `PAUSE && pause[4] == `NO_PAUSE) //执行阶段暂停，访存阶段继续
		begin
			write_data_o <= `ZeroWord;
			write_ce_o <= `WriteDisable;
 			write_addr_o <= 5'b00000;
			hi_o <= `ZeroWord;
			lo_o <= `ZeroWord;
			hilo_write_ce_o <= `WriteDisable;
			
			mem_addr_o <= `ZeroWord;
			mem_wdata_o <= `ZeroWord;
			alu_op_o <= `ALU_NOP_OP;
			
			mem_cp0_wData_o <= `ZeroWord;
			mem_cp0_wAddr_o <= 5'b00000;
			mem_cp0_wCe_o <= `WriteDisable;
		end
		else if(pause[3] == `NO_PAUSE)
		begin
			write_data_o <= write_data_i;
			write_ce_o <= write_ce_i;
 			write_addr_o <= write_addr_i;
			hi_o <= hi_i;
			lo_o <= lo_i;
			hilo_write_ce_o <= hilo_write_ce_i;
			
			mem_addr_o <= mem_addr_i;
			mem_wdata_o <= mem_wdata_i;
			alu_op_o <= alu_op_i;
			
			mem_cp0_wData_o <= ex_cp0_wData_i;
			mem_cp0_wAddr_o <= ex_cp0_wAddr_i;
			mem_cp0_wCe_o <= ex_cp0_wCe_i;
		end

endmodule
